use async_trait::async_trait;
use axum::extract::{FromRequest, Request, Json, rejection::JsonRejection};
use crate::app_resp::AppError;

#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedJsonBody<T>(pub T);

#[async_trait]
impl<T,S> FromRequest<S> for ValidatedJsonBody<T>
where
    T: serde::de::DeserializeOwned + validator::Validate,
    S: Send + Sync,
    Json<T>: FromRequest<S, Rejection = JsonRejection>
{
    type Rejection = AppError;

    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
        let Json(json) = Json::<T>::from_request(req,state).await?;
        json.validate()?;
        Ok(ValidatedJsonBody(json))
    }
}
